#include "StdAfx.h"
#include "ApproachCalcThread.h"

#include <boost/bind.hpp>
#include "Trajectory.h"
#include "EphemParam.h"

CApproachCalcThread::CApproachCalcThread(CAsteroidOrbitParam::Ptr pAsteroidOrbitParam, IApproachHolder	*pApproachHolder)
: m_pAsteroidOrbitParam (pAsteroidOrbitParam)
, m_pApproachHolder (pApproachHolder)
{
	m_pThread = apBoostThread(new boost::thread(boost::bind(&CApproachCalcThread::do_work, this)));
}

CApproachCalcThread::~CApproachCalcThread(void)
{
	m_pThread->join();
}

void CApproachCalcThread::Wait()
{
	m_pThread->join();
}

bool CApproachCalcThread::IsDone(int nWaitMilliSec)
{
	boost::posix_time::time_duration waitPeriod;
	waitPeriod = boost::posix_time::milliseconds(nWaitMilliSec);
	return m_pThread->timed_join(waitPeriod);
}

LPCTSTR CApproachCalcThread::GetErrorStr() const
{
	return (m_strError.IsEmpty())? (LPCTSTR)NULL: m_strError;
}

void CApproachCalcThread::do_work()
{
	m_strError.clear();

	if(m_pApproachHolder == NULL)
		return;

	try
	{
		CEphemParam ephemParam;
		CTrajectory trajectory(ephemParam.GetCurrentEphemPath(), m_pAsteroidOrbitParam);

		SBody body = *m_pAsteroidOrbitParam;
		TimePosTrace PosTrace;
		ListPtrApproachs approachList = trajectory.Move(m_pAsteroidOrbitParam->m_dStart, m_pAsteroidOrbitParam->m_dEnd, body, &PosTrace);
		CApproachTrace::Ptr trace( new CApproachTrace(m_pAsteroidOrbitParam, approachList) );
		m_pApproachHolder->AppendTraceApproaches(trace);
	}
	catch(const CCustomException &e)
	{
		m_strError = e.GetErrorStr();
	}
	catch(...)
	{
		m_strError = _T("Unknown error");
	}
}